/**
  ETFAna project, Anyang Normal University && IMP-CAS
  \class ETFHit
  \brief An abstract base class for a hit. A hit differs from a raw channel in that
  though hit contains the raw channel, it has the attributes of the channel, such
  as the postion and the calibration constants. And a hit always belongs to a detecor.
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2021-10-28
  \date 2021-11-30 last modified
  \attention
  changelog
  <table>
  <tr>  <th>Date         <th>Author      <th>Description                   </tr>
  <tr>  <td>2021-10-28   <td>Asia Sun    <td>file created                  </tr>
  </table>

  \copyright Copyright (c) 2021-2024 Anyang Normal U. && IMP-CAS with LGPLv3 LICENSE
*/

#ifndef ETFHit_h
#define ETFHit_h

#include <string>
#include <TObject.h>

using std::string;

class TGraph;

class ETFHit : public TObject{
public:
  ETFHit();
  ETFHit(const ETFHit &t); ///< copy ctor
  ETFHit &operator=(const ETFHit &t); ///< assignment ctor
  virtual ~ETFHit();

  virtual void Initialize();
  virtual void Reset(){ Initialize(); }
  void SetName(const string &name){ fName = name; }
  const char *GetName() const override{ return fName.data(); }
  void SetPosition(const double *p);
  void SetX(double x){ fPos[0] = x; }
  void SetY(double y){ fPos[1] = y; }
  void SetZ(double z){ fPos[2] = z; }
  void SetFiredStatus(int sta){ fFiredStatus = sta; }
  virtual void SetDelay(double delay){ fDelay = delay; }
  void AppendDelay(double delay){ fDelay += delay; }

  void GetPosition(double *p) const;
  const double *GetPosition() const{ return fPos; }
  double *GetPosition(){ return fPos; }
  double GetPosition(int i) const; // return fPos[i];
  double GetX() const{ return fPos[0]; }
  double GetY() const{ return fPos[1]; }
  double GetZ() const{ return fPos[2]; }
  double x() const{ return fPos[0]; }
  double y() const{ return fPos[1]; }
  double z() const{ return fPos[2]; }
  void GetZX(double &z, double &x) const{ z = fPos[2]; x = fPos[0]; }
  virtual int GetFiredStatus() const{ return fFiredStatus; }
  virtual int fired() const{ return fFiredStatus; }
  virtual void Print(const char *opt = "") const override; ///< print the hit info
  virtual void ConfigureDraw(); ///< configure fGHit
  TGraph *GetGHit() const{ return fGHit; }
  virtual void Draw(const char *opt = "") override; ///< draw the hit
  double GetDelay() const{ return fDelay; }

  ClassDefOverride(ETFHit, 1); ///< ABC for an ETF hit

protected:
  string fName; //!
  ///< assign those member variables that can only be done after all raw data are assigned
  virtual void Assign() = 0;

  int fFiredStatus; ///< fired status, 1: fired; 0: not fired; otherwise: must be specified
  double fPos[3]; ///< the coordinates in the normal plane of the sense wire: [x-y-z]
  double fDelay; //! ///< time delay for the hit

  TGraph *fGHit; //! ///< graph for the hit
};

#endif
